home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C "$Id: keymap.c,v 3.3 1994/05/14 12:43:33 ppessi Exp $";
- /*
- * Keyboard handling routines
- *
- * $Log: keymap.c,v $
- * Revision 3.3 1994/05/14 12:43:33 ppessi
- * Cleaned up the keyboard conversion code,
- * it fully supports CTRL8BIT option now.
- *
- * Revision 3.2 1994/05/12 10:44:49 ppessi
- * Added application keypad handling (original code by R. Knop)
- *
- */
-
- #include <string.h>
- #include <stdio.h>
-
- #include "nifty.h"
- #include "amiga.h"
- #include "display.h"
- #include "wimp.h"
- #include "nio.h"
- #include "napsaprefs.h"
-
- #include <devices/keymap.h>
- #include <intuition/intuition.h>
-
- struct IOStdReq consolereq = { 0 };
- #define ConsoleDevice (consolereq.io_Device)
-
- #ifdef USE_PRAGMAS
- #include <proto/keymap.h>
- #include <clib/console_protos.h>
- #include <pragmas/console_pragmas.h>
- #endif
- #ifdef USE_INLINE
- #include <inline/proto.h>
- #include <inline/console.h>
- #endif
- #ifdef USE_CLIB
- #include <clib/keymap_protos.h>
- #include <clib/console_protos.h>
- #endif
-
- struct KeyMap *default_map = NULL; /* used in `international' mode */
- struct KeyMap *used_map = NULL; /* used in multinational/national mode */
-
- char keyMapDir[] = "Devs:keymaps/";
- #define MAXKEYMAPLEN 32
-
- static struct KeyMap *findmap(const char *name)
- {
- struct KeyMapNode *keymap_n;
- BPTR keySegs;
- char fullKeyMapName[sizeof(keyMapDir) + MAXKEYMAPLEN];
- struct KeyMapResource *keyMapBase =
- (struct KeyMapResource *)OpenResource("keymap.resource");
-
- if (!keyMapBase)
- return NULL;
-
- /* Is it already loaded? */
- keymap_n = (struct KeyMapNode *)
- FindName(&(keyMapBase->kr_List), (UBYTE *)name);
- if (!keymap_n) {
- /* Not found, we load it from devs:keymaps */
- strcpy(fullKeyMapName, keyMapDir);
- strncat(fullKeyMapName, name, MAXKEYMAPLEN);
- keySegs = LoadSeg(fullKeyMapName);
- if (!keySegs)
- return NULL;
- keymap_n = (struct KeyMapNode *)((LONG *) (keySegs << 2) + 1);
- AddHead(&(keyMapBase->kr_List), (struct Node *)keymap_n);
- }
- return &(keymap_n->kn_KeyMap);
- }
-
- /*
- * Use named keymap. If map is non-NULL, use it.
- * Default map is treated as -1
- * Return pointer to new keymap
- *
- * If named keymap can not be found from memory, load it from disk
- */
- void *setmap(const char *name, void *map)
- {
- if (map) {
- if (map != (void *)-1) {
- used_map = map;
- } else {
- used_map = NULL;
- }
- } else if (name) {
- used_map = findmap(name);
- } else {
- used_map = default_map;
- }
-
- if (used_map)
- return used_map;
- else
- return (void *)-1;
- }
-
- /*
- * Initialize keymaps
- */
- void initkeys(void)
- {
- if(OpenDevice("console.device", -1L, (struct IORequest *)&consolereq, 0L))
- fatalError("Failure to open console.device");
-
- default_map = setmap(np.keymap, NULL);
- if (default_map == (struct KeyMap *)-1)
- default_map = NULL;
- }
-
- /*
- * Free resources allocated by this module
- */
- void deinitkeys(void)
- {
- if (ConsoleDevice)
- CloseDevice((struct IORequest *)&consolereq);
- ConsoleDevice = NULL;
- }
-
- /*
- * Handle an Intuition RAWKEY message.
- *
- * The function keys, cursor keys, and keypad may have either the
- * native Amiga values, or the vt100/vt52 values.
- */
- #define ISCURSOR(c) (((c)>75) && ((c)<80))
- #ifdef OWNICONIFY
- #define ICONIFY(c, q) (((q) & AMIGALEFT) && ((q) & AMIGARIGHT) && ((c) == 23))
- #endif
-
- static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize);
-
- void dokeys(struct IntuiMessage *msg)
- {
- UBYTE buf[512], *convertp = buf + sizeof buf / 2, *endp, *sendp;
- int count;
-
- static const char applkeypad[0x60] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 'p', /* 0 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 'q', 'r', 's', /* 1 2 3 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 't', 'u', 'v', /* 4 5 6 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 'n', 'w', 'x', 'y', /* . 7 8 9 */
- 0, 0, 0, 'M', 0, 0, 0, 0, /* Enter */
- 0, 0, 'm', 0, 0, 0, 0, 0, /* - */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 'P', 'Q', 'R', 'S', 'l', 0, /* ( ) / * + */
- };
-
- if (np.applkeypad && msg->Code < 0x60 &&
- applkeypad[(BYTE)(msg->Code)] != 0) {
- /* Application keypad handling */
- convertp[0] = CTRL8('O');
- convertp[1] = applkeypad[(BYTE)(msg->Code)];
- count = 2;
- } else if (ISCURSOR(msg->Code)) {
- /* Cursor keys */
- count = 2;
- convertp[1] = msg->Code - 76 + 'A';
-
- switch (np.cursormap) {
- case CURSOR_VT100:
- convertp[0] = CTRL8('['); /* CSI */
- break;
- case CURSOR_ANSI:
- convertp[0] = CTRL8('O');
- break;
- case CURSOR_VT52:
- convertp[0] = 033;
- break;
- default:
- count = 0;
- }
- } else {
- count = keyconvert(msg, convertp, sizeof(buf) / 2);
- }
-
-
- /* If alt is treated as meta, we add ESC before a single char */
- if (np.altismeta && (msg->Qualifier & IEQUALIFIER_LALT) && count == 1) {
- buf[0] = ESC;
- sendp = buf + 1;
- } else {
- sendp = buf;
- }
-
- ReplyMsg((struct Message *)msg);
-
- /* Convert keycodes before sending them */
- if (count != 0) {
- for (endp = convertp + count; convertp < endp; ) {
- UBYTE c = *convertp++;
-
- if ((c & 0xe0) == 0x80 && !np.ctrl8bit) {
- /* 8-bit control codes are converted into ESC-sequences */
- *sendp++ = ESC;
- c += '@' - 0x80;
- } else if (c == '\015' && np.ansi_LNM) {
- /* CR is converted into CRLF pair */
- *sendp++ = c;
- c = '\012';
- } else if (np.national == NAT_7BIT) {
- /* Characters are converted into national codes */
- c = national_send[c];
- }
-
- *sendp++ = c;
- }
-
- nwrite(buf, sendp - buf);
- }
- }
-
- static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize)
- {
- struct InputEvent ievent;
-
- if(msg->Code & IECODE_UP_PREFIX)
- return 0;
-
- ievent.ie_Code = msg->Code;
-
- /* swap BS and DEL */
- if (ievent.ie_Code == 70 && np.delete)
- ievent.ie_Code = 65;
- else if (ievent.ie_Code == 65 && np.backspace)
- ievent.ie_Code = 70;
-
- ievent.ie_NextEvent = 0;
- ievent.ie_SubClass = 0;
- ievent.ie_Class = IECLASS_RAWKEY;
- ievent.ie_Qualifier = msg->Qualifier;
- ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
- /* This waz a mysterious bug */
- if (np.altismeta) { /* left alt is meta char */
- ievent.ie_Qualifier &= ~IEQUALIFIER_LALT;
- ievent.ie_position.ie_dead.ie_prev1DownQual &= ~IEQUALIFIER_LALT;
- ievent.ie_position.ie_dead.ie_prev2DownQual &= ~IEQUALIFIER_LALT;
- }
-
- return (RawKeyConvert(&ievent, kbuffer, kbsize,
- np.national ? used_map : default_map));
- }
-
-